# YahooSearch class
# @note The class YahooSearch will use an application id of Yahoo which is registered to Richard Cornelissen, please use your own!
# @author Richard Cornelissen

import math, sys
from search.web import WebSearch
from HIT.metasearch import SearchEngine
from time import time
class YahooSearch(SearchEngine):
    APPID = u'ID_COMES_HERE' #TODO: get your own application id here http://developer.yahoo.com/faq/#appid
    NAME = u'Yahoo'
    LOGO = u'yahoo.png'
    MAX_RESULTS = 1000
    
    def __init__(self, query, cache_before = 20):
        self._query = unicode(query)
        cache_before = int(math.ceil(cache_before / 10.0) * 10) #Make sure a multiple of 10 is cached before using this set
        self._results = []
        
        self._get_results(cache_before)
    
    # __getitem__ function, enables the use of YahooSearch[x]
    def __getitem__(self, key):
        try:
            if isinstance(key, int):
                if key >= self.MAX_RESULTS:
                    return None
                
                if key >= len(self._results):
                    self._get_results(key)
                
                return self._results[key]
            
            elif isinstance(key, slice):
                if key.start > self.MAX_RESULTS:
                    return [None]
                
                if key.stop > self.MAX_RESULTS:
                    key.stop = self.MAX_RESULTS
                
                if key.stop >= len(self._results):
                    self._get_results(key.stop)
                
                return self._results[key]
            
        except YahooError:
            return None
    
    def __len__(self):
        return len(self._results)
    
    # Gets results using yahoo API
    def _get_results(self, max):
        max = math.ceil(max/10.0) * 10
        start = len(self._results)
        
        while start <= max:
            num = self._min([50, max-start])
            num = int(math.ceil(num / 10.0) * 10)
            wsearch = WebSearch(YahooSearch.APPID, query = self._query, results = num, start = start)
            info = wsearch.parse_results()
            for r in info.results:
                self._results.append(self._convert_result(r))
            start = len(self._results)
        
        return self._results
    
    # Converts result to a dictionary
    def _convert_result(self, res):
        return {'title': res.Title, 'url': res.Url, 'desc': res.Summary}
    
    def _min(self, l):
        min = l[0]
        for n in l[1:]:
            if n < min:
                min = n
        return min

class YahooError(Exception):
    def __init__(self, query, error):
        self.query = query
        self.error = error